From e2f98922df92eedf50aa5f93f2f4327d436a1c71 Mon Sep 17 00:00:00 2001 From: Tim Starling Date: Sat, 14 Feb 2004 12:37:25 +0000 Subject: [PATCH] Two blocking features: IP range blocks, and expiry times configurable block-by-block. Possible issue: uses strtotime(), which is very handy but in English --- docs/memcached.doc | 7 ++ includes/Block.php | 136 ++++++++++++++++------ includes/BlockCache.php | 115 ++++++++++++++++++ includes/DefaultSettings.php | 15 +-- includes/Setup.php | 17 +++ includes/SpecialBlockip.php | 99 +++++++++++----- includes/SpecialIpblocklist.php | 12 +- includes/User.php | 49 +++----- languages/Language.php | 15 ++- maintenance/InitialiseMessages.inc | 9 +- maintenance/archives/patch-ipb_expiry.sql | 8 ++ maintenance/tables.sql | 1 + update.php | 24 +++- wiki.phtml | 13 --- 14 files changed, 387 insertions(+), 133 deletions(-) create mode 100644 includes/BlockCache.php create mode 100644 maintenance/archives/patch-ipb_expiry.sql diff --git a/docs/memcached.doc b/docs/memcached.doc index e2e016dfc9..6752e9c81d 100644 --- a/docs/memcached.doc +++ b/docs/memcached.doc @@ -122,4 +122,11 @@ Watchlist: stores: HTML string cleared by: nothing, expiry time $wgWLCacheTimeout (1 hour) note: emergency optimisation only + +IP blocks: + key: $wgDBname:ipblocks + ex: wikidb:ipblocks + stores: array of arrays, for the BlockCache class + cleared by: BlockCache:clear() + ... more to come ... diff --git a/includes/Block.php b/includes/Block.php index 3da568e81b..13cb657aa7 100644 --- a/includes/Block.php +++ b/includes/Block.php @@ -8,12 +8,15 @@ # # To use delete(), you only need to fill $mAddress +# Globals used: $wgIPBlockCache, $wgAutoblockExpiry + class Block { - var $mAddress, $mUser, $mBy, $mReason, $mTimestamp, $mAuto, $mId; + /* public*/ var $mAddress, $mUser, $mBy, $mReason, $mTimestamp, $mAuto, $mId, $mExpiry; + /* private */ var $mNetworkBits, $mIntegerAddr; function Block( $address = "", $user = "", $by = 0, $reason = "", - $timestamp = "" , $auto = 0) + $timestamp = "" , $auto = 0, $expiry = "" ) { $this->mAddress = $address; $this->mUser = $user; @@ -21,21 +24,27 @@ class Block $this->mReason = $reason; $this->mTimestamp = $timestamp; $this->mAuto = $auto; - } + $this->mExpiry = $expiry; - /*static*/ function newFromDB( $address, $user = 0, $killExpired = true ) { + $this->initialiseRange(); + } + + /*static*/ function newFromDB( $address, $user = 0, $killExpired = true ) + { $ban = new Block(); $ban->load( $address, $user, $killExpired ); return $ban; } - - function clear() { + + function clear() + { $mAddress = $mReason = $mTimestamp = ""; $mUser = $mBy = 0; } # Get a ban from the DB, with either the given address or the given username - function load( $address, $user = 0, $killExpired = true ) { + function load( $address, $user = 0, $killExpired = true ) + { $fname = "Block::load"; $ret = false; $killed = false; @@ -83,7 +92,8 @@ class Block return $ret; } - function initFromRow( $row ) { + function initFromRow( $row ) + { $this->mAddress = $row->ipb_address; $this->mReason = $row->ipb_reason; $this->mTimestamp = $row->ipb_timestamp; @@ -91,10 +101,30 @@ class Block $this->mBy = $row->ipb_by; $this->mAuto = $row->ipb_auto; $this->mId = $row->ipb_id; + $this->mExpiry = $row->ipb_expiry; + + $this->initialiseRange(); } + function initialiseRange() + { + if ( $this->mUser == 0 ) { + $rangeParts = explode( "/", $this->mAddress ); + if ( count( $rangeParts ) == 2 ) { + $this->mNetworkBits = $rangeParts[1]; + } else { + $this->mNetworkBits = 32; + } + $this->mIntegerAddr = ip2long( $rangeParts[0] ); + } else { + $this->mNetworkBits = false; + $this->mIntegerAddr = false; + } + } + # Callback with a Block object for every block - /*static*/ function enumBlocks( $callback, $tag, $killExpired = true ) { + /*static*/ function enumBlocks( $callback, $tag, $killExpired = true ) + { $sql = "SELECT * FROM ipblocks ORDER BY ipb_timestamp DESC"; $res = wfQuery( $sql, DB_READ, "Block::enumBans" ); $block = new Block(); @@ -112,7 +142,8 @@ class Block wfFreeResult( $res ); } - function delete() { + function delete() + { $fname = "Block::delete"; if ( $this->mAddress == "" ) { $sql = "DELETE FROM ipblocks WHERE ipb_id={$this->mId}"; @@ -121,17 +152,23 @@ class Block wfStrencode( $this->mAddress ) . "'"; } wfQuery( $sql, DB_WRITE, "Block::delete" ); + + $this->clearCache(); } - function insert() { + function insert() + { $sql = "INSERT INTO ipblocks - (ipb_address, ipb_user, ipb_by, ipb_reason, ipb_timestamp, ipb_auto ) + (ipb_address, ipb_user, ipb_by, ipb_reason, ipb_timestamp, ipb_auto, ipb_expiry ) VALUES ('" . wfStrencode( $this->mAddress ) . "', {$this->mUser}, {$this->mBy}, '" . - wfStrencode( $this->mReason ) . "','{$this->mTimestamp}', {$this->mAuto})"; + wfStrencode( $this->mReason ) . "','{$this->mTimestamp}', {$this->mAuto}, '{$this->mExpiry}')"; wfQuery( $sql, DB_WRITE, "Block::insert" ); + + $this->clearCache(); } - function deleteIfExpired() { + function deleteIfExpired() + { if ( $this->isExpired() ) { $this->delete(); return true; @@ -140,31 +177,64 @@ class Block } } - function isExpired() { - global $wgIPBlockExpiration, $wgUserBlockExpiration; - - $period = $this->mUser ? $wgUserBlockExpiration : $wgIPBlockExpiration; - - # Period==0 means no expiry - if ( !$period ) { - return false; - } - $expiry = wfTimestamp2Unix( $this->mTimestamp ) + $period; - $now = wfTimestamp2Unix( wfTimestampNow() ); - if ( $now > $expiry ) { - return true; - } else { - return false; - } + function isExpired() + { + return wfTimestampNow() > $this->mExpiry; } - function isValid() { + function isValid() + { return $this->mAddress != ""; } function updateTimestamp() { - wfQuery( "UPDATE ipblocks SET ipb_timestamp='" . wfTimestampNow() . - "' WHERE ipb_address='" . wfStrencode( $this->mAddress ) . "'", DB_WRITE, "Block::updateTimestamp" ); + + $this->mTimestamp = wfTimestampNow(); + $this->mExpiry = Block::getAutoblockExpiry( $this->mTimestamp ); + + wfQuery( "UPDATE ipblocks SET " . + "ipb_timestamp='" . $this->mTimestamp . "', " . + "ipb_expiry='" . $this->mExpiry . "' " . + "WHERE ipb_address='" . wfStrencode( $this->mAddress ) . "'", DB_WRITE, "Block::updateTimestamp" ); + + $this->clearCache(); + } + + /* private */ function clearCache() + { + global $wgBlockCache; + if ( is_object( $wgBlockCache ) ) { + $wgBlockCache->clear(); + } + } + + function getIntegerAddr() + { + return $this->mIntegerAddr; + } + + function getNetworkBits() + { + return $this->mNetworkBits; + } + + /* static */ function getAutoblockExpiry( $timestamp ) + { + global $wgAutoblockExpiry; + return wfUnix2Timestamp( wfTimestamp2Unix( $timestamp ) + $wgAutoblockExpiry ); + } + + /* static */ function normaliseRange( $range ) + { + $parts = explode( "/", $range ); + if ( count( $parts ) == 2 ) { + $shift = 32 - $parts[1]; + $ipint = ip2long( $parts[0] ); + $ipint = $ipint >> $shift << $shift; + $newip = long2ip( $ipint ); + $range = "$newip/{$parts[1]}"; + } + return $range; } } diff --git a/includes/BlockCache.php b/includes/BlockCache.php new file mode 100644 index 0000000000..48921a4e07 --- /dev/null +++ b/includes/BlockCache.php @@ -0,0 +1,115 @@ +mMemcKey = "$dbName:ipblocks"; + + if ( !$deferLoad ) { + $this->load(); + } + } + + function load() + { + global $wgUseMemCached, $wgMemc; + + if ( $this->mData === false) { + $this->mData = array(); + + $saveMemc = false; + # Try memcached + if ( $wgUseMemCached ) { + $this->mData = $wgMemc->get( $this->mMemcKey ); + if ( !$this->mData ) { + $saveMemc = true; + } + } + + if ( $this->mData === false || is_null( $this->mData ) ) { + # Load from DB + $this->mData = array(); + Block::enumBlocks( "wfBlockCacheInsert", "" ); # Calls $this->insert() + } + + if ( $saveMemc ) { + $wgMemc->set( $this->mMemcKey, $this->mData, 0 ); + } + } + } + + function insert( &$block ) + { + if ( $block->mUser == 0 ) { + $nb = $block->getNetworkBits(); + $ipint = $block->getIntegerAddr(); + $index = $ipint >> ( 32 - $nb ); + + if ( !array_key_exists( $nb, $this->mData ) ) { + $this->mData[$nb] = array(); + } + + $this->mData[$nb][$index] = 1; + } + } + + function get( $ip ) + { + $this->load(); + $ipint = ip2long( $ip ); + $blocked = false; + + foreach ( $this->mData as $networkBits => $blockInts ) { + if ( array_key_exists( $ipint >> ( 32 - $networkBits ), $blockInts ) ) { + $blocked = true; + break; + } + } + if ( $blocked ) { + # Clear low order bits + if ( $networkBits != 32 ) { + $ip .= "/$networkBits"; + $ip = Block::normaliseRange( $ip ); + } + $block = new Block(); + $block->load( $ip ); + } else { + $block = false; + } + + return $block; + } + + function clear() + { + global $wgUseMemCached, $wgMemc; + + $this->mData = false; + if ( $wgUseMemCached ) { + $wgMemc->delete( $this->mMemcKey ); + } + } + + function clearLocal() + { + $this->mData = false; + } +} + +function wfBlockCacheInsert( $block, $tag ) +{ + global $wgBlockCache; + $wgBlockCache->insert( $block ); +} diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 45b862a769..c24eec9430 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -113,17 +113,10 @@ $wgWhitelistEdit = false; $wgWhitelistRead = false; $wgWhitelistAccount = array ( "user" => 1, "sysop" => 1, "developer" => 1 ); $wgSysopUserBans = false; # Allow sysops to ban logged-in users -$wgIPBlockExpiration = 86400; # IP blocks expire after this many seconds, 0=infinite -$wgUserBlockExpiration = 0; # As above, but for logged-in users - -# User agent/range blocking -# Blocks all users using a particular user agent, possibly restricted to a -# set of IP ranges. Note: you can't block all user agents by leaving -# $wgBadUserAgents blank. That would block nothing. -$wgBadRanges = false; # e.g. array(array("1.2.3.0", "1.2.3.255")) -$wgBadUserAgents = false; # e.g. array("OfflineExplorer/1.0") -$wgRangeBlockUser = 0; # The block is attributed to this user ID -$wgRangeBlockReason = ""; # This reason is given (should be in wfMsg, obviously) +$wgSysopRangeBans = false; # Allow sysops to ban IP ranges +$wgDefaultBlockExpiry = "24 hours"; # default expiry time + # strtotime format, or "infinite" for an infinite block +$wgAutoblockExpiry = 86400; # Number of seconds before autoblock entries expire # Client-side caching: $wgCachePages = true; # Allow client-side caching of pages diff --git a/includes/Setup.php b/includes/Setup.php index 2149dce12f..b85f107bbe 100644 --- a/includes/Setup.php +++ b/includes/Setup.php @@ -48,6 +48,7 @@ include_once( "Block.php" ); include_once( "SearchEngine.php" ); include_once( "DifferenceEngine.php" ); include_once( "MessageCache.php" ); +include_once( "BlockCache.php" ); wfProfileOut( "$fname-includes" ); wfProfileIn( "$fname-memcached" ); @@ -56,6 +57,21 @@ global $wgArticle, $wgDeferredUpdateList, $wgLinkCache; global $wgMemc, $wgMagicWords, $wgMwRedir, $wgDebugLogFile; global $wgMessageCache, $wgUseMemCached, $wgUseDatabaseMessages; global $wgMsgCacheExpiry, $wgDBname, $wgCommandLineMode; +global $wgBlockCache; + +# Useful debug output +if ( function_exists( "getallheaders" ) ) { + wfDebug( "\nStart request\n" ); + wfDebug( "$REQUEST_METHOD $REQUEST_URI\n" ); + $headers = getallheaders(); + foreach ($headers as $name => $value) { + wfDebug( "$name: $value\n" ); + } + wfDebug( "\n" ); +} else { + wfDebug( "$REQUEST_METHOD $REQUEST_URI\n" ); +} + class MemCachedClientforWiki extends memcached { function _debugprint( $text ) { @@ -134,6 +150,7 @@ if( !$wgCommandLineMode && isset( $_COOKIE[ini_get("session.name")] ) ) { User::SetupSession(); } +$wgBlockCache = new BlockCache( true ); $wgUser = User::loadFromSession(); $wgDeferredUpdateList = array(); $wgLinkCache = new LinkCache(); diff --git a/includes/SpecialBlockip.php b/includes/SpecialBlockip.php index 023ca54440..4b29d03134 100644 --- a/includes/SpecialBlockip.php +++ b/includes/SpecialBlockip.php @@ -8,7 +8,7 @@ function wfSpecialBlockip() $wgOut->sysopRequired(); return; } - $fields = array( "wpBlockAddress", "wpBlockReason" ); + $fields = array( "wpBlockAddress", "wpBlockReason", "wpBlockExpiry" ); wfCleanFormFields( $fields ); $ipb = new IPBlockForm(); @@ -21,16 +21,24 @@ class IPBlockForm { function showForm( $err ) { - global $wgOut, $wgUser, $wgLang; - global $ip, $wpBlockAddress, $wpBlockReason; + global $wgOut, $wgUser, $wgLang, $wgDefaultBlockExpiry; + global $ip, $wpBlockAddress, $wpBlockExpiry, $wpBlockReason; $wgOut->setPagetitle( wfMsg( "blockip" ) ); $wgOut->addWikiText( wfMsg( "blockiptext" ) ); - if ( ! $wpBlockAddress ) { $wpBlockAddress = $ip; } - $ipa = wfMsg( "ipaddress" ); - $reason = wfMsg( "ipbreason" ); - $ipbs = wfMsg( "ipbsubmit" ); + if ( ! $wpBlockAddress ) { + $wpBlockAddress = $ip; + } + + if ( is_null( $wpBlockExpiry ) || $wpBlockExpiry === "" ) { + $wpBlockExpiry = $wgDefaultBlockExpiry; + } + + $mIpaddress = wfMsg( "ipaddress" ); + $mIpbexpiry = wfMsg( "ipbexpiry" ); + $mIpbreason = wfMsg( "ipbreason" ); + $mIpbsubmit = wfMsg( "ipbsubmit" ); $action = wfLocalUrlE( $wgLang->specialPage( "Blockip" ), "action=submit" ); @@ -38,19 +46,28 @@ class IPBlockForm { $wgOut->setSubtitle( wfMsg( "formerror" ) ); $wgOut->addHTML( "

{$err}\n" ); } + + $scBlockAddress = htmlspecialchars( $wpBlockAddress ); + $scBlockExpiry = htmlspecialchars( $wpBlockExpiry ); + $scBlockReason = htmlspecialchars( $wpBlockReason ); + $wgOut->addHTML( "

- + + + - +
{$ipa}:{$mIpaddress}: + +
{$mIpbexpiry}: - +
{$reason}:{$mIpbreason}: - +
  - +
\n" ); @@ -59,25 +76,54 @@ class IPBlockForm { function doSubmit() { global $wgOut, $wgUser, $wgLang; - global $ip, $wpBlockAddress, $wpBlockReason, $wgSysopUserBans; + global $ip, $wpBlockAddress, $wpBlockReason, $wpBlockExpiry; + global $wgSysopUserBans, $wgSysopRangeBans; $userId = 0; $wpBlockAddress = trim( $wpBlockAddress ); - - if ( ! preg_match( "/^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/", - $wpBlockAddress ) ) - { - if ( $wgSysopUserBans ) { - $userId = User::idFromName( $wpBlockAddress ); - if ( $userId == 0 ) { - $this->showForm( wfMsg( "badipaddress" ) ); + $rxIP = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'; + + # Check for invalid specifications + if ( ! preg_match( "/^$rxIP$/", $wpBlockAddress ) ) { + if ( preg_match( "/^($rxIP)\\/(\\d{1,2})$/", $wpBlockAddress, $matches ) ) { + if ( $wgSysopRangeBans ) { + if ( $matches[2] > 31 || $matches[2] < 1 ) { + $this->showForm( wfMsg( "ip_range_invalid" ) ); + } + $wpBlockAddress = Block::normaliseRange( $wpBlockAddress ); + } else { + # Range block illegal + $this->showForm( wfMsg( "range_block_disabled" ) ); return; } } else { - $this->showForm( wfMsg( "badipaddress" ) ); - return; - } + # Username block + if ( $wgSysopUserBans ) { + $userId = User::idFromName( $wpBlockAddress ); + if ( $userId == 0 ) { + $this->showForm( wfMsg( "nosuchuser", htmlspecialchars( $wpBlockAddress ) ) ); + return; + } + } else { + $this->showForm( wfMsg( "badipaddress" ) ); + return; + } + } + } + + if ( $wpBlockExpiry == "infinite" || $wpBlockExpiry == "indefinite" ) { + $expiry = 0; + } else { + # Convert GNU-style date, returns -1 on error + $expiry = strtotime( $wpBlockExpiry ); } + + if ( $expiry < 0 ) { + $this->showForm( wfMsg( "ipb_expiry_invalid" ) ); + return; + } + $expiry = wfUnix2Timestamp( $expiry ); + if ( "" == $wpBlockReason ) { $this->showForm( wfMsg( "noblockreason" ) ); return; @@ -85,13 +131,14 @@ class IPBlockForm { # Create block # Note: for a user block, ipb_address is only for display purposes + $ban = new Block( $wpBlockAddress, $userId, $wgUser->getID(), - wfStrencode( $wpBlockReason ), wfTimestampNow(), 0 ); + wfStrencode( $wpBlockReason ), wfTimestampNow(), 0, $expiry ); $ban->insert(); # Make log entry $log = new LogPage( wfMsg( "blocklogpage" ), wfMsg( "blocklogtext" ) ); - $action = wfMsg( "blocklogentry", $wpBlockAddress ); + $action = wfMsg( "blocklogentry", $wpBlockAddress, $wpBlockExpiry ); $log->addEntry( $action, $wpBlockReason ); # Report to the user diff --git a/includes/SpecialIpblocklist.php b/includes/SpecialIpblocklist.php index 9368bd4e3f..30bef110a2 100644 --- a/includes/SpecialIpblocklist.php +++ b/includes/SpecialIpblocklist.php @@ -117,9 +117,15 @@ function wfAddRow( $block, $tag ) { $name = User::whoIs( $block->mBy ); $ulink = $sk->makeKnownLink( $wgLang->getNsText( Namespace::getUser() ). ":{$name}", $name ); - $d = $wgLang->timeanddate( $block->mTimestamp, true ); - - $line = wfMsg( "blocklistline", $d, $ulink, $addr ); + $formattedTime = $wgLang->timeanddate( $block->mTimestamp, true ); + + if ( $block->mExpiry === "" ) { + $formattedExpiry = "indefinite"; + } else { + $formattedExpiry = $wgLang->timeanddate( $block->mExpiry, true ); + } + + $line = wfMsg( "blocklistline", $formattedTime, $ulink, $addr, $formattedExpiry ); $wgOut->addHTML( "
  • {$line}" ); diff --git a/includes/User.php b/includes/User.php index 4851b99177..9bf1d4c821 100644 --- a/includes/User.php +++ b/includes/User.php @@ -94,45 +94,29 @@ class User { /* private */ function getBlockedStatus() { - global $wgBadRanges, $wgBadUserAgents, $wgRangeBlockUser, $wgRangeBlockReason, $wgIP; + global $wgIP, $wgBlockCache; if ( -1 != $this->mBlockedby ) { return; } + + $this->mBlockedby = 0; - # Range/user-agent blocking - - $fBlock = false; # Mmmm, Hungarian - if ( ( !is_array( $wgBadUserAgents ) || - array_key_exists( getenv( "HTTP_USER_AGENT" ), $wgBadUserAgents ) ) && - is_array( $wgBadRanges ) ) - { - $iIp = ip2long( $wgIP ); - foreach ( $wgBadRanges as $range ) { - $start = ip2long( $range[0] ); - $end = ip2long( $range[1] ); - if ( $iIp >= $start && $iIp <= $end ) { - $fBlock = true; - break; - } + # User blocking + if ( $this->mId ) { + $block = new Block(); + if ( $block->load( $wgIP , $this->mId ) ) { + $this->mBlockedby = $block->mBy; + $this->mBlockreason = $block->mReason; } } - if ( $fBlock ) { - $this->mBlockedby = $wgRangeBlockUser; - $this->mBlockreason = $wgRangeBlockReason; - return; - } - - # User/IP blocking - - $block = new Block(); - if ( !$block->load( $wgIP , $this->mId ) ) { - wfDebug( $wgIP ." is not blocked\n" ); - $this->mBlockedby = 0; - return; + # IP/range blocking + if ( !$this->mBlockedby ) { + $block = $wgBlockCache->get( $wgIP ); + if ( $block !== false ) { + $this->mBlockedby = $block->mBy; + $this->mBlockreason = $block->mReason; + } } - - $this->mBlockedby = $block->mBy; - $this->mBlockreason = $block->mReason; } function isBlocked() @@ -626,6 +610,7 @@ class User { $ipblock->mReason = wfMsg( "autoblocker", $this->getName(), $userblock->mReason ); $ipblock->mTimestamp = wfTimestampNow(); $ipblock->mAuto = 1; + $ipblock->mExpiry = Block::getAutoblockExpiry( $ipblock->mTimestamp ); # Insert it $ipblock->insert(); diff --git a/languages/Language.php b/languages/Language.php index 1f779af64a..bf9924792e 100644 --- a/languages/Language.php +++ b/languages/Language.php @@ -643,11 +643,6 @@ The reason given is this:
    ''$2''

    You may contact $1 or one of the other Note that you may not use the \"email this user\" feature unless you have a valid email address registered in your [[Special:Preferences|user preferences]]. Your IP address is $3. Please include this address in any queries you make. - -==Note to AOL users== -Due to continuing acts of vandalism by one particular AOL user, Wikipedia often blocks AOL proxies. Unfortunately, a single proxy server may be used by a large number of AOL users, and hence innocent AOL users are often inadvertently blocked. We apologise for any inconvenience caused. - -If this happens to you, please email an administrator, using an AOL email address. Be sure to include the IP address given above. ", "whitelistedittitle" => "Login required to edit", "whitelistedittext" => "You have to [[Special:Userlogin|login]] to edit articles.", @@ -1208,9 +1203,10 @@ accordance with [[$wgMetaNamespace:Policy|policy]]. Fill in a specific reason below (for example, citing particular pages that were vandalized).", "ipaddress" => "IP Address/username", +"ipbexpiry" => "Expiry", "ipbreason" => "Reason", "ipbsubmit" => "Block this user", -"badipaddress" => "No user exists by that name", +"badipaddress" => "Invalid IP address", "noblockreason" => "You must supply a reason for the block.", "blockipsuccesssub" => "Block succeeded", "blockipsuccesstext" => "\"$1\" has been blocked. @@ -1221,17 +1217,20 @@ to a previously blocked IP address or username.", "ipusubmit" => "Unblock this address", "ipusuccess" => "\"$1\" unblocked", "ipblocklist" => "List of blocked IP addresses and usernames", -"blocklistline" => "$1, $2 blocked $3", +"blocklistline" => "$1, $2 blocked $3 (expires $4)", "blocklink" => "block", "unblocklink" => "unblock", "contribslink" => "contribs", "autoblocker" => "Autoblocked because you share an IP address with \"$1\". Reason \"$2\".", "blocklogpage" => "Block_log", -"blocklogentry" => 'blocked "$1"', +"blocklogentry" => 'blocked "$1" with an expiry time of $2', "blocklogtext" => "This is a log of user blocking and unblocking actions. Automatically blocked IP addresses are not be listed. See the [[Special:Ipblocklist|IP block list]] for the list of currently operational bans and blocks.", "unblocklogentry" => 'unblocked "$1"', +"range_block_disabled" => "The sysop ability to create range blocks is disabled.", +"ipb_expiry_invalid" => "Expiry time invalid.", +"ip_range_invalid" => "Invalid IP range.\n", # Developer tools # diff --git a/maintenance/InitialiseMessages.inc b/maintenance/InitialiseMessages.inc index 5eeb0d2c42..315ab64e3f 100755 --- a/maintenance/InitialiseMessages.inc +++ b/maintenance/InitialiseMessages.inc @@ -74,8 +74,7 @@ function initialiseMessages( $overwrite = false) { $doInsert = true; if ( $overwrite ) { - $sql = "DELETE FROM cur WHERE cur_namespace=$ns AND cur_title='$title'"; - wfQuery( $sql, DB_WRITE, $fname ); + wfQuery( "DELETE FROM cur WHERE cur_namespace=$ns AND cur_title='$title'", DB_WRITE, $fname ); } else { if (array_key_exists($title, $exists)) { $doInsert = false; @@ -112,7 +111,11 @@ function initialiseMessages( $overwrite = false) { } print "Done\n"; print "Writing..."; - wfQuery( $sql, DB_WRITE, $fname ); + + if ( !$first ) { + wfQuery( $sql, DB_WRITE, $fname ); + } + print "Done\n"; $navText .= ""; diff --git a/maintenance/archives/patch-ipb_expiry.sql b/maintenance/archives/patch-ipb_expiry.sql new file mode 100644 index 0000000000..d41c8771da --- /dev/null +++ b/maintenance/archives/patch-ipb_expiry.sql @@ -0,0 +1,8 @@ +-- Adds the ipb_expiry field to ipblocks + +ALTER TABLE ipblocks ADD ipb_expiry char(14) binary NOT NULL default ''; + +-- All IP blocks have one day expiry +UPDATE ipblocks SET ipb_expiry = date_format(date_add(ipb_timestamp,INTERVAL 1 DAY),"%Y%m%d%H%i%s") WHERE ipb_user = 0; + +-- Null string is fine for user blocks, since this indicates infinity diff --git a/maintenance/tables.sql b/maintenance/tables.sql index 8a9d79a729..71f55259d3 100644 --- a/maintenance/tables.sql +++ b/maintenance/tables.sql @@ -126,6 +126,7 @@ CREATE TABLE ipblocks ( ipb_reason tinyblob NOT NULL default '', ipb_timestamp char(14) binary NOT NULL default '', ipb_auto tinyint(1) NOT NULL default '0', + ipb_expiry char(14) binary NOT NULL default '', UNIQUE KEY ipb_id (ipb_id) ) TYPE=MyISAM PACK_KEYS=1; diff --git a/update.php b/update.php index 5dac7718a6..58f8e3c1e2 100644 --- a/update.php +++ b/update.php @@ -154,13 +154,29 @@ function update_passwords() { function do_ipblocks_update() { global $wgDatabase; - if ( $wgDatabase->fieldExists( "ipblocks", "ipb_id" ) ) { - echo "...ipblocks table is up to date.\n"; - } else { + + $do1 = $do2 = false; + + if ( !$wgDatabase->fieldExists( "ipblocks", "ipb_id" ) ) { + $do1 = true; + } + if ( !$wgDatabase->fieldExists( "ipblocks", "ipb_expiry" ) ) { + $do2 = true; + } + + if ( $do1 || $do2 ) { echo "Updating ipblocks table... "; - dbsource( "maintenance/archives/patch-ipblocks.sql", $wgDatabase ); + if ( $do1 ) { + dbsource( "maintenance/archives/patch-ipblocks.sql", $wgDatabase ); + } + if ( $do2 ) { + dbsource( "maintenance/archives/patch-ipb_expiry.sql", $wgDatabase ); + } echo "ok\n"; + } else { + echo "...ipblocks is up to date.\n"; } + } diff --git a/wiki.phtml b/wiki.phtml index 35fdcd98b4..4093459b09 100644 --- a/wiki.phtml +++ b/wiki.phtml @@ -16,19 +16,6 @@ include_once( "Setup.php" ); wfProfileIn( "main-misc-setup" ); OutputPage::setEncodings(); # Not really used yet -# Useful debug output -if ( function_exists( "getallheaders" ) ) { - wfDebug( "\nStart request\n" ); - wfDebug( "$REQUEST_METHOD $REQUEST_URI\n" ); - $headers = getallheaders(); - foreach ($headers as $name => $value) { - wfDebug( "$name: $value\n" ); - } - wfDebug( "\n" ); -} else { - wfDebug( "$REQUEST_METHOD $REQUEST_URI\n" ); -} - # Query string fields # global $action, $title, $search, $go, $target, $printable; -- 2.20.1